package com.eairlv.route.client.configuration;

import com.eairlv.route.client.core.RouteClient;
import com.eairlv.route.client.core.RouteInvocationHandlerFactory;
import com.eairlv.route.client.core.RouteLoadBalancerFeignClient;
import com.eairlv.route.client.service.RouteLoadService;
import feign.Client;
import feign.Feign;
import feign.InvocationHandlerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.cloud.openfeign.ribbon.CachingSpringLoadBalancerFactory;
import org.springframework.context.annotation.Bean;

/**
 *
 *  如果需要自定义组装基于{@link com.eairlv.route.client.annotation.RouteKey}的spel表达式的值，需要创建任意配置类，并创建
 *  自定义路由拦截器实现{@link com.eairlv.route.client.interceptor.RouteInterceptor}，重写相关方法，并注入bean，如：
 *
 *  @Configuration
 *  public class CustomConfiguration {
 *
 *     @Bean
 *     RouteInterceptor routeInterceptor(){
 *         return new CustomRouteInterceptor();
 *     }
 *  }
 *
 *  public class CustomRouteInterceptor implements RouteInterceptor {
 *
 *     @Override
 *     public String applyKey(Object key, Integer type, Method method, Object[] args, Target target) {
 *         return key.toString();
 *     }
 *
 *     @Override
 *     public Integer applyType(Object key, Integer type, Method method, Object[] args, Target target) {
 *         return type;
 *     }
 *
 *     @Override
 *     public RouteForm applyRoute(RouteHandlerForm routeHandlerForm, Method method, Object[] args, Target target) {
 *         RouteForm routeForm = BeanUtil.copyProperties(routeHandlerForm, RouteForm.class);
 *         routeForm.setKey(routeHandlerForm.toString());
 *         return routeForm;
 *     }
 *  }
 *
 * @author eairlv
 * @description
 * @date 11:08 2019/12/9
 */
public class RouteConfiguration {

    /**
     * 替换invocationHandlerFactory
     * @return
     */
    @Bean
    @ConditionalOnBean(RouteLoadService.class)
    Feign.Builder invocationHandlerFactory(RouteLoadService routeLoadService){
        InvocationHandlerFactory invocationHandlerFactory = new RouteInvocationHandlerFactory(routeLoadService);
        return Feign.builder().invocationHandlerFactory(invocationHandlerFactory);
    }

    /**
     * 替换Client
     * @param cachingFactory
     * @param clientFactory
     * @return
     */
    @Bean
    public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
                              SpringClientFactory clientFactory) {
        return new RouteLoadBalancerFeignClient(new RouteClient(null, null),
                cachingFactory, clientFactory);
    }
}
